package com.omega.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.omega.exam.Constants.Constants;
import com.omega.exam.Exception.BaseException;
import com.omega.exam.entity.Question;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.omega.exam.entity.QuestionAnswer;
import com.omega.exam.entity.QuestionChoice;
import com.omega.exam.mapper.QuestionAnswerMapper;
import com.omega.exam.mapper.QuestionChoiceMapper;
import com.omega.exam.mapper.QuestionMapper;
import com.omega.exam.service.QuestionService;
import com.omega.exam.utils.ExcelUtil;
import com.omega.exam.vo.PageResult;
import com.omega.exam.vo.QuestionImportVo;
import io.netty.util.internal.ObjectUtil;
import jakarta.annotation.Resource;
import jodd.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 题目Service实现类
 * 实现题目相关的业务逻辑
 */
@Slf4j
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private QuestionChoiceMapper questionChoiceMapper;
    @Resource
    private QuestionAnswerMapper questionAnswerMapper;
    @Resource
    private RedisTemplate redisTemplate;

    public PageResult getQuestionlist(Integer page, Integer size, Long categoryId, String difficulty, String type, String keyword) {
        PageResult pageResult = new PageResult();
        IPage<Question> page1 = new Page<>(page, size);
        IPage<Question> list = questionMapper.selectByPage(page1, categoryId, difficulty, type, keyword);


        for (Question question : list.getRecords()) {
            LambdaQueryWrapper<QuestionChoice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(QuestionChoice::getQuestionId, question.getId());
            List<QuestionChoice> list1 = questionChoiceMapper.selectList(lambdaQueryWrapper);
            question.setChoices(list1);
            LambdaQueryWrapper<QuestionAnswer> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(QuestionAnswer::getQuestionId, question.getId());
            List<QuestionAnswer> questionAnswer = questionAnswerMapper.selectList(lambdaQueryWrapper1);
            Map<Long, QuestionAnswer> answerMap = questionAnswer.stream().collect(Collectors.toMap(QuestionAnswer::getQuestionId, a -> a));
            System.out.println(answerMap);
            question.setAnswer(answerMap.get(question.getId()));

        }
        pageResult.setRecords(list.getRecords());
        pageResult.setTotal(list.getTotal());
        return pageResult;


    }

    public Question getQuestionById(Long id) {
        Question question = questionMapper.selectById(id);
        if (question == null) {
            throw new BaseException("题目不存在");
        }
        LambdaQueryWrapper<QuestionAnswer> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QuestionAnswer::getQuestionId, id);
//        QuestionAnswer questionAnswer=questionAnswerMapper.selectOne(lambdaQueryWrapper);
        List<QuestionAnswer> list = questionAnswerMapper.selectList(lambdaQueryWrapper);
        Map<Long, QuestionAnswer> map = list.stream().collect(Collectors.toMap(QuestionAnswer::getQuestionId, a -> a));

        question.setAnswer(map.get(id));
        LambdaQueryWrapper<QuestionChoice> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(QuestionChoice::getQuestionId, id);
        List<QuestionChoice> list1 = questionChoiceMapper.selectList(lambdaQueryWrapper1);
        question.setChoices(list1);
        new Thread(() -> {
            increamentQuestion(question.getId());
        }).start();
        return question;
    }

    private void increamentQuestion(Long id) {
        //增阿吉有序集合中的数量
        Double score = Double.valueOf(redisTemplate.opsForZSet().incrementScore(Constants.POPULAR_QUESTIONS_KEY, id, 1));

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void savequestion(Question question) {
        LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Question::getType, question.getType());
        lambdaQueryWrapper.eq(Question::getTitle, question.getTitle());
        Question question1 = questionMapper.selectOne(lambdaQueryWrapper);
        if (question1 != null) {
            throw new BaseException("同一类型下不能存在相同题目");
        }
        questionMapper.insert(question);
        QuestionAnswer questionAnswer = question.getAnswer();
        questionAnswer.setQuestionId(question.getId());
        if ("CHOICE".equals(question.getType())) {
            List<QuestionChoice> choices = question.getChoices();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < choices.size(); i++) {
                QuestionChoice choice = choices.get(i);
                choice.setSort(i);
                choice.setQuestionId(question.getId());
                questionChoiceMapper.insert(choice);
                if (choice.getIsCorrect()) {
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append((char) ('A' + i));
                }
            }
            questionAnswer.setAnswer(sb.toString());
        }
        questionAnswerMapper.insert(questionAnswer);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editquestion(Question question) {
        LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(Question::getId, question.getId());
        lambdaQueryWrapper.eq(Question::getType, question.getType());
        lambdaQueryWrapper.eq(Question::getTitle, question.getTitle());
        Question question1 = questionMapper.selectOne(lambdaQueryWrapper);
        if (question1 != null) {
            throw new BaseException("同一类型下不能存在相同题目");
        }
        questionMapper.updateById(question);

        LambdaQueryWrapper<QuestionChoice> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(QuestionChoice::getQuestionId, question.getId());
        questionChoiceMapper.delete(lambdaQueryWrapper1);
        LambdaQueryWrapper<QuestionAnswer> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper2.eq(QuestionAnswer::getQuestionId, question.getId());


        QuestionAnswer questionAnswer = questionAnswerMapper.selectOne(lambdaQueryWrapper2);
        if ("CHOICE".equals(question.getType())) {
            List<QuestionChoice> list = question.getChoices();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < list.size(); i++) {
                QuestionChoice questionChoice = list.get(i);
                questionChoice.setSort(i);
                questionChoice.setQuestionId(question.getId());
                questionChoiceMapper.insert(questionChoice);
                if (questionChoice.getIsCorrect().equals(true)) {
                    questionAnswer.setQuestionId(question.getId());
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append((char) ('A' + i));

                }
            }
            questionAnswer.setAnswer(sb.toString());
        }
        questionAnswerMapper.updateById(questionAnswer);


    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByid(Long id) {
        Question question = questionMapper.selectById(id);
        if (question == null) {
            throw new BaseException("题目不存在");
        }
        questionMapper.deleteById(id);
        LambdaQueryWrapper<QuestionChoice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QuestionChoice::getQuestionId, id);
        questionChoiceMapper.delete(lambdaQueryWrapper);

        LambdaQueryWrapper<QuestionAnswer> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(QuestionAnswer::getQuestionId, id);
        questionAnswerMapper.delete(lambdaQueryWrapper1);

    }

    public List<Question> querypopular(Integer size) {
        List<Question> popularlist = new ArrayList<>();
        //按分数倒序查看缓存的题目id
        ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();

        Set<Object> popilarIds = redisTemplate.opsForZSet().reverseRange(Constants.POPULAR_QUESTIONS_KEY, 0, size - 1);
        System.out.println(popilarIds + "o");
        if (!ObjectUtils.isEmpty(popilarIds)) {
            //处理热门题目
            //object转long类型
            List<Long> list = popilarIds.stream().map(id -> Long.valueOf(id.toString())).collect(Collectors.toList());
            System.out.println(list);
//            List<Question> questionList=listByIds(list);
            for (Long id : list) {
                Question question = questionMapper.selectById(id);
                if (question != null) {
                    popularlist.add(question);
                }
            }
        }
        //检查是否满足6条
        int diff = size - popularlist.size();
        if (diff > 0) {
            LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.orderByDesc(Question::getCreateTime);
            //已有的id进行过滤
            List<Long> exisQuestionId = popularlist.stream().map(Question::getId).collect(Collectors.toList());
            lambdaQueryWrapper.notIn(Question::getId, exisQuestionId);
            //切割指定的diff，只获取两条
            lambdaQueryWrapper.last("limit " + diff);
            List<Question> list = questionMapper.selectList(lambdaQueryWrapper);
            popularlist.addAll(list);

        }
        for (Question question : popularlist) {
            LambdaQueryWrapper<QuestionChoice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(QuestionChoice::getQuestionId, question.getId());
            List<QuestionChoice> list = questionChoiceMapper.selectList(lambdaQueryWrapper);
            question.setChoices(list);
            question.setViewCount(zSetOperations.score(Constants.POPULAR_QUESTIONS_KEY, question.getId()));
            LambdaQueryWrapper<QuestionAnswer> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(QuestionAnswer::getQuestionId, question.getId());
            QuestionAnswer questionAnswer = questionAnswerMapper.selectOne(lambdaQueryWrapper1);
            question.setAnswer(questionAnswer);
        }

        return popularlist;

    }

    @Transactional(rollbackFor = Exception.class)
    public List<QuestionImportVo> previewExcel(MultipartFile file) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new BaseException("预览文件为空");
        }
        String fileName = file.getOriginalFilename();
        if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) {
            throw new BaseException("预览文件错误");
        }
        List<QuestionImportVo> questionImportlist = ExcelUtil.parseExcel(file);
        return questionImportlist;
    }
    @Transactional(rollbackFor = Exception.class)
    public Integer importBatchQuestions(List<QuestionImportVo> questions) {
        if (questions == null || questions.isEmpty()) {
            throw new BaseException("导入的题目为空");
        }
        int successcount = 0;
        for (int i = 0; i < questions.size(); i++) {
            try {
                Question question = convertQuestionImportVoTOQuestion(questions.get(i));
                successcount++;
            } catch (Exception e) {

            }
        }
        return successcount;
    }

    private Question convertQuestionImportVoTOQuestion(QuestionImportVo questionImportVo) {
      LambdaQueryWrapper<Question> lambdaQueryWrapper=new LambdaQueryWrapper<>();
      lambdaQueryWrapper.eq(Question::getType,questionImportVo.getType());
        lambdaQueryWrapper.eq(Question::getTitle,questionImportVo.getTitle());
        Question question1=questionMapper.selectOne(lambdaQueryWrapper);
        if(question1 !=null){
            throw new BaseException("该分类下存在相同题目");
        }
        Question question = new Question();
        question.setAnalysis(questionImportVo.getAnalysis());
//        question.setAnswer(questionImportVo.getAnswer());
        question.setCategoryId(questionImportVo.getCategoryId());
        question.setDifficulty(questionImportVo.getDifficulty());
        question.setMulti(questionImportVo.getMulti());
        question.setScore(questionImportVo.getScore());
        question.setTitle(questionImportVo.getTitle());
        question.setType(questionImportVo.getType());
        questionMapper.insert(question);
        if (question.getType().equals("CHOICE")) {
            List<QuestionImportVo.ChoiceImportDto> list = questionImportVo.getChoices();
            QuestionAnswer questionAnswer = new QuestionAnswer();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < list.size(); i++) {

                QuestionChoice questionChoice = new QuestionChoice();
                questionChoice.setQuestionId(question.getId());
                questionChoice.setSort(i);
                questionChoice.setContent(list.get(i).getContent());
                questionChoice.setIsCorrect(list.get(i).getIsCorrect());
                questionChoiceMapper.insert(questionChoice);
                if (list.get(i).getIsCorrect()) {
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append((char) ('A' + i));
                }

            }
            questionAnswer.setQuestionId(question.getId());
            questionAnswer.setAnswer(sb.toString());
            System.out.println(questionAnswer.getQuestionId());
            System.out.println(questionAnswer.getAnswer());
            questionAnswerMapper.insert(questionAnswer);
        }
        return question;

    }
} 